package com.jin.spirng_boot_learn.services.impl;

import com.jin.spirng_boot_learn.domain.Book;
import com.jin.spirng_boot_learn.domain.ClassRoom;
import com.jin.spirng_boot_learn.domain.Student;
import com.jin.spirng_boot_learn.repository.CityRepository;
import com.jin.spirng_boot_learn.repository.ClassRoomRepository;
import com.jin.spirng_boot_learn.repository.StudentDataRestRepository;
import com.jin.spirng_boot_learn.services.StudentClassSerivce;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.util.Optional;

@Service
public class StudentClassSerivceImp implements StudentClassSerivce {

    @Resource
    private StudentDataRestRepository studentDataRestRepository;

    @Autowired
    private PlatformTransactionManager txManager;

    @Autowired
    private TransactionTemplate transactionTemplate;


    @Resource
    private ClassRoomRepository classRoomRepository;

    @Resource
    private CityRepository cityRepository;

    public void getClazz() {
        Optional<ClassRoom> byId = classRoomRepository.findById(1L);
        ClassRoom classRoom = byId.get();
        classRoom.setName("aaaaaaa");
    }

    @Override
    @Transactional
    public void createClass() {
        Student student = new Student();
        student.setName("zhangjin");
        student.setPassportNumber("123");

        ClassRoom classRoom = new ClassRoom();
        classRoom.setName("一年一班");
        classRoom.setNumber(12);

        Book book = new Book();

        book.setName("杭州");

        studentDataRestRepository.save(student);
        System.out.println("insert student");
        try {
            int restul = 123 / 0;
            classRoomRepository.save(classRoom);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        cityRepository.save(book);
        System.out.println("11111");
    }

    @Override
    public void createPart() {
        //
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void createStudent() {
        Student student = new Student();
        student.setName("zhangjin123");
        student.setPassportNumber("123");
        studentDataRestRepository.save(student);
        try {
            createClassWithError();
        } catch (Exception e) {
            return;
        }

    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void createClassWithError() {
        ClassRoom classRoom = new ClassRoom();
        classRoom.setName("一年一班");
        classRoom.setNumber(12);
        classRoomRepository.save(classRoom);
//        try {
//            throw new RuntimeException();
//        } catch (Exception e
//                ) {
//            return;
//        }
        throw new RuntimeException();
    }

    @Override
    public void createStudentWithTransactionManager() {

        transactionTemplate.execute(status -> {
            // execute your code
            new Student();
            Student student = new Student();
            student.setName("before transaction");
            student.setPassportNumber("123");
            studentDataRestRepository.save(student);
            int error = 1 / 0;
            student.setName("after transaction");
            studentDataRestRepository.save(student);
            return null;
        });


    }

    @Override
    public void createStudentWithTransactionTemplate() {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setName("SomeTxName");
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = txManager.getTransaction(def);
        try {
            // execute your business logic here
            new Student();
            Student student = new Student();
            student.setName("before transaction");
            student.setPassportNumber("123");
            studentDataRestRepository.save(student);
            int error = 1 / 0;
            student.setName("after transaction");
            studentDataRestRepository.save(student);
        } catch (Exception ex) {
            txManager.rollback(status);
            throw ex;
        }
        txManager.commit(status);

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void createFatherTransaction(){
        Student student = new Student();
        student.setName("Father");
        student.setPassportNumber("3-24");
        studentDataRestRepository.save(student);

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void createSonTransaction(){
        Student student = new Student();
        student.setName("Son");
        student.setPassportNumber("3-24");
        studentDataRestRepository.save(student);
        int i = 1 / 0;
    }


}
